package com.buaa.aimall.authModule.service.impl;

import com.buaa.aimall.authModule.dto.UserIdentityDTO;
import com.buaa.aimall.authModule.exception.TokenException;
import com.buaa.aimall.authModule.service.TokenService;
import com.buaa.aimall.userModule.Entity.UserEntity;
import com.buaa.aimall.userModule.Service.UserService;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import jakarta.annotation.PostConstruct;

import java.security.Key;
import java.util.Date;

/**
 * Token服务实现类
 */
@Service
public class TokenServiceImpl implements TokenService {

    private final UserService userService;
    
    // 密钥，应从配置文件中获取
    @Value("${jwt.secret:defaultSecretKeyWhichShouldBeAtLeast32BytesLong}")
    private String secret;
    
    // token有效期（毫秒）
    @Value("${jwt.expiration:86400000}")
    private long expiration;
    
    @Autowired
    public TokenServiceImpl(UserService userService) {
        this.userService = userService;
    }
    
    @PostConstruct
    public void init() {
        System.out.println("TokenServiceImpl初始化完成，密钥长度: " + secret.length());
    }
    
    @Override
    public String generateToken(String userId) {
        try {
            System.out.println("开始生成token，用户ID: " + userId);
            
            // 检查userId是否为空
            if (userId == null || userId.trim().isEmpty()) {
                System.out.println("用户ID为空");
                throw new TokenException("用户ID不能为空");
            }
            
            System.out.println("开始查询用户信息");
            // 查询用户信息
            UserEntity user = userService.getById(userId);
            System.out.println("用户查询结果: " + user);
            
            if (user == null) {
                System.out.println("用户不存在，ID: " + userId);
                throw new TokenException("用户不存在");
            }
            
            // 生成JWT密钥
            System.out.println("开始生成JWT密钥");
            Key key = Keys.hmacShaKeyFor(secret.getBytes());
            
            // 设置JWT签发时间和过期时间
            Date now = new Date();
            Date expiryDate = new Date(now.getTime() + expiration);
            System.out.println("令牌有效期设置为: " + expiration + " 毫秒, 从 " + now + " 到 " + expiryDate);
            
            // 生成JWT
            System.out.println("开始构建JWT");
            String token = Jwts.builder()
                    .setSubject(userId)
                    .claim("username", user.getUsername())
                    .setIssuedAt(now)
                    .setExpiration(expiryDate)
                    .signWith(key, SignatureAlgorithm.HS256)
                    .compact();
            
            System.out.println("JWT生成成功，长度: " + token.length());
            return token;
        } catch (TokenException e) {
            System.out.println("生成Token时发生TokenException: " + e.getMessage());
            e.printStackTrace();
            throw e;
        } catch (Exception e) {
            System.out.println("生成Token时发生异常: " + e.getMessage());
            e.printStackTrace();
            throw new TokenException("生成Token时发生错误: " + e.getMessage(), e);
        }
    }
    
    @Override
    public UserIdentityDTO verifyToken(String token) {
        try {
            System.out.println("开始验证token");
            
            // 检查token是否为空
            if (token == null || token.trim().isEmpty()) {
                System.out.println("Token为空");
                throw new TokenException("Token不能为空");
            }
            
            // 解析JWT
            System.out.println("开始解析JWT");
            Key key = Keys.hmacShaKeyFor(secret.getBytes());
            Claims claims = Jwts.parserBuilder()
                    .setSigningKey(key)
                    .build()
                    .parseClaimsJws(token)
                    .getBody();
            
            // 提取用户信息
            String userId = claims.getSubject();
            String username = claims.get("username", String.class);
            Date issuedAt = claims.getIssuedAt();
            Date expiresAt = claims.getExpiration();
            
            System.out.println("Token验证成功，用户ID: " + userId + ", 用户名: " + username);
            
            // 返回用户身份DTO
            return new UserIdentityDTO(userId, username, issuedAt, expiresAt);
        } catch (ExpiredJwtException e) {
            System.out.println("Token已过期: " + e.getMessage());
            e.printStackTrace();
            throw new TokenException("Token已过期");
        } catch (Exception e) {
            System.out.println("验证Token时发生异常: " + e.getMessage());
            e.printStackTrace();
            throw new TokenException("无效的Token: " + e.getMessage(), e);
        }
    }
} 